package com.pearl.study05.demo.controller;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.lang.Opt;
import cn.hutool.core.util.ObjectUtil;
import com.pearl.study05.demo.common.R;
import com.pearl.study05.demo.vo.CommentVO;
import com.pearl.study05.demo.vo.TaskVO;
import com.sun.jdi.connect.Connector;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.camunda.bpm.engine.TaskService;
import org.camunda.bpm.engine.task.Comment;
import org.camunda.bpm.engine.task.Task;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;

/**
 * `TaskService`任务服务，用于对任务进行管理，包括：
 * <p>
 * <p>
 * 对用户任务（UserTask）管理和流程控制
 * 设置用户任务（UserTask）的权限信息（拥有者、候选人、办理人）
 * 针对用户任务添加用户附件、任务评论和事件记录
 * TaskService对Task管理与流程控制
 * <p>
 * Task对象的创建，删除
 * 查询Task、并驱动Task节点完成执行
 * Task相关参数变量（variable）设置
 * TaskService设置Task权限信息
 * <p>
 * 候选用户（candidateUser）和候选组（candidateGroup）
 * 指定拥有人（Owner）和办理人（Assignee）
 * 通过claim设置办理人
 * TaskService设置Task附加信息
 * <p>
 * 任务附件（Attachment）创建与查询
 * 任务评论（Comment）创建与查询
 * 事件记录（Event）创建与查询
 *
 * @author TD
 * @version 1.0
 * @date 2023/7/31
 */
@RequestMapping("/task")
@RestController
@Tag(name = "任务服务")
public class TaskController {

    @Autowired
    private TaskService taskService;

    @PostMapping("/newTask")
    @Operation(summary = "新建任务")
    public R<TaskVO> newTask(String taskId, String assignee, String taskName) {
        // 新建
        Task task = taskService.newTask(taskId);
        task.setAssignee(assignee);
        task.setName(taskName);
        // 保存
        taskService.saveTask(task);
        return R.success(TaskVO.fromTask(task));
    }

    @PostMapping("/updateTask")
    @Operation(summary = "修改任务")
    public R<TaskVO> updateTask(String taskId, String assignee, String taskName) {
        // 查询
        Task task = taskService.createTaskQuery().taskId(taskId).singleResult();
        Opt.ofNullable(task).orElseThrow(IllegalArgumentException::new, "参数错误");
        // 修改
        task.setAssignee(assignee);
        task.setName(taskName);
        // 保存或更新
        taskService.saveTask(task);
        return R.success(TaskVO.fromTask(task));
    }

    @PostMapping("/deleteTask")
    @Operation(summary = "删除任务")
    public R<?> deleteTask(String taskId, String deleteReason) {
        taskService.deleteTask(taskId, deleteReason);
        return R.success();
    }

    @PostMapping("/claim")
    @Operation(summary = "声明任务的负责人")
    public R<?> claim(String taskId, String userId) {
        taskService.claim(taskId, userId);
        return R.success();
    }

    @PostMapping("/transfer")
    @Operation(summary = "转办")
    public R<?> transfer(String taskId, String userId) {
        taskService.setAssignee(taskId, userId);
        taskService.setOwner(taskId, userId);
        return R.success();
    }


    @PostMapping("/myTask")
    @Operation(summary = "查询我的任务")
    public R<List<TaskVO>> myTask(String assignee) {
        List<Task> list = taskService.createTaskQuery()
                .taskAssignee(assignee)
                .list();
        List<TaskVO> result = new ArrayList<>();
        if (CollUtil.isNotEmpty(list)) {
            for (Task task : list) {
                TaskVO vo = new TaskVO();
                vo.setId(task.getId());
                vo.setAssignee(task.getAssignee());
                vo.setName(task.getName());
                vo.setProcessDefinitionId(task.getProcessDefinitionId());
                result.add(vo);
            }
        }
        return R.success(result);
    }


    @PostMapping("/completeAndComment")
    @Operation(summary = "根据ID完成待办并添加审批意见")
    @Transactional
    public R<?> completeAndComment(String taskId, String message) {
        taskService.createComment(taskId, null, message);
        taskService.complete(taskId);
        return R.success();
    }

    @PostMapping("/createAttachment")
    @Operation(summary = "添加附件")
    @Transactional
    public R<?> completeAndComment(@RequestParam MultipartFile file, String taskId) throws IOException {
        InputStream inputStream = file.getInputStream();
        taskService.createAttachment("类型", taskId, null, file.getOriginalFilename(), "全文描述", inputStream);
        inputStream.close();
        return R.success();
    }


    @PostMapping("/getTaskComments")
    @Operation(summary = "根据ID获取审批意见")
    public R<List<CommentVO>> getTaskComments(String taskId) {
        List<Comment> taskComments = taskService.getTaskComments(taskId);
        List<CommentVO> list = new ArrayList<>();
        if (CollUtil.isNotEmpty(taskComments)) {
            for (Comment taskComment : taskComments) {
                CommentVO vo = new CommentVO();
                vo.setId(taskComment.getId());
                vo.setFullMessage(taskComment.getFullMessage());
                vo.setTaskId(taskComment.getTaskId());
                list.add(vo);
            }
        }
        return R.success(list);
    }
}
